//============================================================================
// Name        : queue_region.cpp
// Author      : dfoelber
//============================================================================

// INCLUDES //
#include "physics/path.h"
#include "queue_region.h"
#include "render_manager.h"
#include "image_manager.h"
#include <iostream>
#include <time.h>
//////////////

using namespace std;

/**
* Constructor
**/
QueueRegion::QueueRegion()
{
	srand( time(NULL) );
}

/**
* Destructor
**/
QueueRegion::~QueueRegion()
{
	for( int i = 0; i < (int)queue.size(); i++ )
	{
		delete queue[i];
	}
}

/**
* Initializes the region, filling the queue.
**/
void QueueRegion::Initialize()
{
	for( int i = 0; i < MAX_QUEUE_SIZE; i++ )
	{
		Queue();
	}
}

/**
* Notify the region of an event.
* 
* Overridden from Region.
* 
* @param event The event that happened
* @return If the region used the event
**/
bool QueueRegion::ProcessEvent( SDL_Event event )
{
	return Region::ProcessEvent( event );
}

/**
* Notifies of time passing.
* 
* Overridden from Region.
* 
* @param The amount of time, in milliseconds, that passed since the last call
**/
void QueueRegion::TimePassed( int ms )
{
	Region::TimePassed( ms );
}

/**
* Renders the objects on the background
* 
* Overridden from Region.
**/
void QueueRegion::Render()
{
	Region::Render();
}

/**
* Gets the top pair of gems in the queue.
* 
* @return The top pair of gems
**/
QueueRegion::PuzzlePair* QueueRegion::GetTopPair()
{
	if( (int)queue.size() == 0 )
		return NULL;
	
	else return queue.back();
}

/**
* Dequeues the top pair of gems and queues another pair.
**/
void QueueRegion::Dequeue()
{
	PuzzlePair* pair = queue.back();
	
	for( int i = 0; i < (int)objects.size(); i++ )
	{
		objects[i]->GetPath()->SetPosition(objects[i]->GetPath()->GetX(),
				objects[i]->GetPath()->GetY() - objects[i]->GetPath()->GetHeight());
	}
	
	// don't delete later
	RemoveObject(pair->first, false);
	RemoveObject(pair->second, false);
	
	queue.pop_back();
	
	Queue();
}

/** 
* Calculates and returns the next gem to spawn.
* 
* @return The next Id (defined in Object.h)
**/
int QueueRegion::CalculateNextGem()
{
	int r = 15, b = 15, y = 15, g = 15, w = 15, l = 15; // the alignments with default values
	
	if( alignmentRegion )
	{
		r = alignmentRegion->GetRedAlignment();
		r = (r + 11) * 20;
		b = alignmentRegion->GetBlueAlignment();
		b = (b + 11) * 20;
		y = alignmentRegion->GetYellowAlignment();
		y = (y + 11) * 20;
		g = alignmentRegion->GetGreenAlignment();
		g = (g + 11) * 20;
		w = alignmentRegion->GetWhiteAlignment();
		w = (w + 11) * 20;
		l = alignmentRegion->GetBlackAlignment();
		l = (l + 11) * 20;
	}
	
	int total = r + b + y + g + w + l;
	int color = rand() % total;
	
	if( color < r )
		return OBJECT_ID_RED_GEM;
	else if( color < r + b )
		return OBJECT_ID_BLUE_GEM;
	else if( color < r + b + y )
		return OBJECT_ID_YELLOW_GEM;
	else if( color < r + b + y + g )
		return OBJECT_ID_GREEN_GEM;
	else if( color < r + b + y + g + w )
		return OBJECT_ID_WHITE_GEM;
	else
		return OBJECT_ID_BLACK_GEM;
}

/** 
* Translates an object Id to an image Id
* 
* @param Id The object Id
* @return The image Id (defined in ImageManager.h)
**/
XYNE_IMAGE QueueRegion::TranslateToImageId(int Id)
{
	switch (Id)
	{
	case OBJECT_ID_RED_GEM:
		return IMAGE_RED_GEM;
	case OBJECT_ID_BLUE_GEM:
		return IMAGE_BLUE_GEM;
	case OBJECT_ID_YELLOW_GEM:
		return IMAGE_YELLOW_GEM;
	case OBJECT_ID_GREEN_GEM:
		return IMAGE_GREEN_GEM;
	case OBJECT_ID_WHITE_GEM:
		return IMAGE_WHITE_GEM;
	}
	
	return IMAGE_BLACK_GEM;
}

/**
* Queues a pair of gems.
**/
void QueueRegion::Queue()
{
	int y = GetBoundary()->GetY() + (ImageManager::GetManager()->GetImage( IMAGE_GREEN_GEM )->GetHeight() * (int)queue.size());
	
	int id = CalculateNextGem();
	Object* first = new Object( ImageManager::GetManager()->GetImage( TranslateToImageId(id) ), id );
	first->SetPosition( GetBoundary()->GetX(), y );
	AddObject( first );
	
	id = CalculateNextGem();
	Object* second = new Object( ImageManager::GetManager()->GetImage( TranslateToImageId(id) ), id );
	second->SetPosition( GetBoundary()->GetX() + first->GetSurface()->GetWidth(), y );
	AddObject( second );
	
	PuzzlePair* pair = new PuzzlePair();
	pair->first = first;
	pair->second = second;
	queue.insert(queue.begin(), pair);
}
